package com.mrzhou.study.struct.support;

/**
 * 运算符号栈:  用来保存算术中字符常量的数据
 * 为加深不同线性结构显现栈的异同, 这里用单链表实现
 */
public class CharStack {

    private Node top; // 链表栈的栈顶指针
    private int size; // 当前链表栈的大小
    private int maxSize; // 未防止链表无限扩大, 这里使用maxSize限制

    public CharStack(int maxSize) {
        this.maxSize = maxSize;
    }

    /**
     * 压栈
     * @param elem
     */
    public void push(char elem) {
        if(isFull()) { // 如链表栈到达最大限制. 直接放回
            return;
        }
        this.top = new Node(elem, top);
        size++; // 链表容量加一
    }

    /**
     * 出栈
     * @return
     */
    public char pop() {
        if(isEmpty()) {
            return ' ';
        }
        char elem = top.elem;
        this.top = top.next;
        return elem;
    }

    /**
     * 查看当前的栈顶数据
     */
    public char peek() {
        if(isEmpty()) {
            return ' ';
        }
        return top.elem;
    }

    public static void main(String[] args) {
        CharStack stack = new CharStack(3);
        stack.pop();
        stack.push('3');
        stack.push('2');
        stack.push('1');
        stack.push('0');
        stack.pop();
        stack.pop();
        stack.pop();
    }

    /**
     *  比较算术运算符的优先级, 返回的int越大则运算符的优先级越高
     */
    public int priority(char oper) {
        if(oper == '*' || oper == '/') {
            return 1;
        }
        if(oper == '+' || oper == '-') {
            return 0;
        }
        return -1;
    }

    public boolean isLegalChar(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')';
    }

    public boolean isOper(char c) {
        return c == '+' || c == '-' || c == '*' || c == '/';
    }

    public boolean isOpers(char... chars) {
        for(char c: chars) {
            if(!this.isOper(c)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 这里是将栈中的数据逆序放置
     */
    public CharStack reversal() {
        CharStack charStack = new CharStack(size);
        if(!isEmpty()) {
            Node cur = this.top;
            while (cur.next != null) {
                charStack.push(cur.elem);
                cur = cur.next;
            }
            charStack.push(cur.elem);
        }
        return charStack;
    }

    public String toString() {
        StringBuffer sb = new StringBuffer("[");
        if(isEmpty()) {
            return sb.append(" ]").toString();
        }
        Node current = this.top;
        while(current.next != null) {
            sb.append(current.elem).append(", ");
            current = current.next;
        }
        return sb.append(current.elem).append("]").toString();
    }

    public boolean isEmpty() {
        return top == null;
    }

    public boolean isFull() {
        return size == maxSize;
    }

    private class Node {
        char elem;
        Node next;

        Node(char elem, Node next) {
            this.elem = elem;
            this.next = next;
        }

        public String toString() {
            return String.valueOf(elem);
        }

    }

}
